<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
// +----------------------------------------------------------------------
// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: 流年 <liu21st@gmail.com>
// +----------------------------------------------------------------------

use think\Db;
// 应用公共文件
use think\facade\{
    Config,Session,Log,Request,Cache,Cookie,Route
};

// 团队积累
// 单字幕函数 +----------------------------------------------------------------------
/**
 * 打印变量,断点
 *
 * @param unknown $a 变量
 * @param string $b 是否打印变量类型
 */
function t($a, $b = false)
{
    echo "<pre>";
    if ($b) {
        var_dump($a);
    } else {
        print_r($a);
    }
    exit("</pre>");
}

/**
 * 页面输出
 *
 * @param string $msg  信息
 * @param string $exit 是否阻断
 */
function e($msg = '', $exit = false)
{
    if ($exit) {
        exit("------------------{$msg}-------------------<br>");
    } else {
        echo ("------------------{$msg}-------------------<br>");
    }
}


/**
 * URL重定向
 * @param string $url 重定向的URL地址
 * @param integer $time 重定向的等待时间（秒）
 * @param string $msg 重定向前的提示信息
 * @return 跳转页面
 */
function r($url, $time = 0, $msg = '')
{
    if (empty($msg))
        $msg = "系统将在{$time}秒之后自动跳转到{$url}！";

    if (! headers_sent()) {
        if (0 === $time) {
            header('Location: ' . $url);
        } else {
            header("refresh:{$time};url={$url}");
            echo ($msg);
        }
    } else {
        $str = "<meta http-equiv='Refresh' content='{$time};URL={$url}'>";
        if ($time != 0) {
            $str .= $msg;
        }
        echo ($str);
    }
    exit();
}

/**
 * 获取配置
 * @param string $name 配置一级键值的名称
 * @param string $key 配置二级键值的名称
 * @return \think\mixed
 */
function c($name = '', $key = '')
{
    $rs = config($name);
    if ($key !== '') {
        return isset($rs[$key]) ? $rs[$key] : "";
    }
    return $rs;
}


// 判断函数 +----------------------------------------------------------------------
function is_post()
{
    return request()->isPost();
}
// js跳转页面
function js_url($url = '', $second=1)
{
    $s = bcmul($second, 1000);
    if ($url) {
        exit("<script>setTimeout(function(){window.location.href='" . $url . "';},".$s.");</script>");
    } else {
        exit("<script>setTimeout('window.location.reload();',".$s.");</script>");
    }
}
// 验证数组是否有为空或0的
function check_arr($arr = []){
    foreach($arr as $v){
        if(!$v) return false;
    }
    return true;
}

//api常用函数 +----------------------------------------------------------------------
function err($msg='未知错误',$code=100){

    $domain = $_SERVER['HTTP_HOST'];
    $arr = explode(".",$domain);
    if($arr[0]!='api' && $arr[0]!='192'){
        $temp = ['code'=>$code, 'js'=>session('js'),'msg'=>$msg, 'data'=>[]];
    }else{
        $temp = ['code'=>$code,'msg'=>$msg, 'data'=>[]];
    }
    return json($temp);
}
function suc($data=[], $count=0){
    $count = (int)$count;
    if($data==null || $data=='') $data = [];

    $domain = $_SERVER['HTTP_HOST'];
    $arr = explode(".",$domain);
    if($arr[0]!='api' && $arr[0]!='192'){
        $temp = ['code'=>0, 'js'=>session('js'),'msg'=>'操作成功','count'=>$count, 'data'=>$data];
    }else{
        $temp = ['code'=>0, 'msg'=>'操作成功','count'=>$count, 'data'=>$data];
    }
    return json($temp);
}
/**
* 简单对称加密算法之加密
* @param String $string 需要加密的字串
* @param String $skey 加密EKY
* @return String
*/
function encode($string = '', $skey = 'abcd') {
    $strArr = str_split(base64_encode($string));
    $strCount = count($strArr);
    foreach (str_split($skey) as $key => $value)
        $key < $strCount && $strArr[$key].=$value;
    return str_replace(array('=', '+', '/'), array('O0O0O', 'o000o', 'oo00o'), join('', $strArr));
}

/**
* 简单对称加密算法之解密
* @param String $string 需要解密的字串
* @param String $skey 解密KEY
* @return String
*/
function decode($string = '', $skey = 'abcd') {
    $strArr = str_split(str_replace(array('O0O0O', 'o000o', 'oo00o'), array('=', '+', '/'), $string), 2);
    $strCount = count($strArr);
    foreach (str_split($skey) as $key => $value)
        $key <= $strCount  && isset($strArr[$key]) && $strArr[$key][1] === $value && $strArr[$key] = $strArr[$key][0];
    return base64_decode(join('', $strArr));
}

/**
 * 签名
 * @param unknown $data 数组
 * @param unknown $keys app key值
 * @return true or false
 */
function sign($data,$keys)
{
    #配置: '应用编号'=>'秘钥',
    $app_config = [
        "5100"=>'ios_app_secret',#ios
        "5200"=>'android_app_secret',#安卓
        "5300"=>'h5_app_secret',#h5
        "5400"=>'pc_app_secret',#pc
    ];
    if(isset($data['sign'])) unset($data['sign']);
    if(isset($data['app_key'])) unset($data['app_key']);
    $temp_k = array_keys($data);
    sort($temp_k);
    $str = $keys;
    foreach($temp_k as $k){
        if(isset($data[$k]) && is_string($data[$k])) $str .= $k.$data[$k];
    }
    $str .= $app_config[$keys];
    return strtoupper(sha1($str));
}
/**
 * 格式化字节大小
 * @param  number $size 字节数
 * @param  string $delimiter 数字和单位分隔符
 * @return string            格式化后的带单位的大小
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function format_bytes($size, $delimiter = '') {
    $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
    for ($i = 0; $size >= 1024 && $i < 5; $i++) {
        $size /= 1024;
    }
    return $size . $delimiter . $units[$i];
}

/**
 * 字符串截取，支持中文和其他编码
 * @param string $str 需要转换的字符串
 * @param int|string $start 开始位置
 * @param string $length 截取长度
 * @param string $charset 编码格式
 * @param bool|string $suffix 截断显示字符
 * @return string
 */
function msubstr($str, $start = 0, $length, $charset = "utf-8", $suffix = true) {
    if (function_exists("mb_substr")) {
        $slice = mb_substr($str, $start, $length, $charset);
    } elseif (function_exists('iconv_substr')) {
        $slice = iconv_substr($str, $start, $length, $charset);
        if (false === $slice) {
            $slice = '';
        }
    } else {
        $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
        $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
        $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
        $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
        preg_match_all($re[$charset], $str, $match);
        $slice = join("", array_slice($match[0], $start, $length));
    }
    return $suffix ? $slice . '...' : $slice;
}

/**
 *  不区分大小写的in_array实现
 * @author staitc7 <static7@qq.com>
 * @param $value
 * @param $array
 * @return bool
 */
function in_array_case($value, $array = [])
{
    return in_array(strtolower($value), array_map('strtolower', $array ?? []));
}
/**
 *  分析枚举类型配置值
 *  格式 a:名称1,b:名称2
 * @param string $string 配置值
 * @return array
 */
function parse_config_attr($string) {
    $array = preg_split('/[,;\r\n]+/', trim($string, ",;\r\n"));
    if (strpos($string, ':')) {
        $value = [];
        foreach ($array as $val) {
            list($k, $v) = explode(':', $val);
            $value[$k] = $v;
        }
    } else {
        $value = $array;
    }
    return $value;
}
/** Json数据格式化
 * @param  Mixed  $data   数据
 * @param  String $indent 缩进字符，默认4个空格
 * @return JSON
 */
function jsonFormat($data, $indent=null){
    $data = urldecode($data);
    // 缩进处理
    $ret = '';
    $pos = 0;
    $length = strlen($data);
    $indent = isset($indent)? $indent : '    ';
    $newline = "\n";
    $prevchar = '';
    $outofquotes = true;
    for($i=0; $i<=$length; $i++){
        $char = substr($data, $i, 1);
        if($char=='"' && $prevchar!='\\'){
            $outofquotes = !$outofquotes;
        }elseif(($char=='}' || $char==']') && $outofquotes){
            $ret .= $newline;
            $pos --;
            for($j=0; $j<$pos; $j++){
                $ret .= $indent;
            }
        }
        $ret .= $char;
        if(($char==',' || $char=='{' || $char=='[') && $outofquotes){
            $ret .= $newline;
            if($char=='{' || $char=='['){
                $pos ++;
            }

            for($j=0; $j<$pos; $j++){
                $ret .= $indent;
            }
        }
        $prevchar = $char;
    }
    return $ret;
}
/**
 * 把返回的数据集转换成Tree
 * @param array $list 要转换的数据集
 * @param string $pk
 * @param string $pid parent标记字段
 * @param string $child level标记字段
 * @param int $root 根
 * @return array
 * @author 麦当苗儿 <zuojiazi@vip.qq.com>
 */
function list_to_tree($list, $pk = 'id', $pid = 'pid', $child = '_child', $root = 0) {
    // 创建Tree
    $tree = [];
    if (is_array($list)) {
        // 创建基于主键的数组引用
        $refer = [];
        foreach ($list as $key => $data) {
            $refer[$data[$pk]] = &$list[$key];
        }
        foreach ($list as $key => $data) {
            // 判断是否存在parent
            $parentId = $data[$pid];
            if ($root == $parentId) {
                $tree[] = &$list[$key];
            } else {
                if (isset($refer[$parentId])) {
                    $parent = &$refer[$parentId];
                    $parent[$child][] = &$list[$key];
                }
            }
        }
    }
    return $tree;
}



// 通用函数 +----------------------------------------------------------------------
/**
 * 系统非常规MD5加密方法
 * @param  string $str 要加密的字符串
 * @param string $key 默认密钥
 * @return string
 */
function com_password($str='123456', $key = '')
{
    $key = empty($key) ? Env::get('password_secret') : $key;
    return (string)$str === '' ? '' : md5(sha1($str) . $key);
}
/**
 * 产生token值
 * @param string $user_id 用户id, 或者其他
 */
function com_token($user_id = '')
{
    $str = time() . rand(1000, 9999) . $user_id;
    return md5($str);
}

/**
 * 时间戳格式化
 * @param int $time
 * @param string $format 时间格式, f:友好
 * @return string 完整的时间显示
 */
function com_time_format($time = null, $format = 'Y-m-d H:i:s') {
    if((int)$time < 1) return '';
    if($format=='f'){
        $now=time();
        $day=date('Y-m-d',$time);
        $today=date('Y-m-d');

        $dayArr=explode('-',$day);
        $todayArr=explode('-',$today);

        //距离的天数，这种方法超过30天则不一定准确，但是30天内是准确的，因为一个月可能是30天也可能是31天
        $days=($todayArr[0]-$dayArr[0])*365+(($todayArr[1]-$dayArr[1])*30)+($todayArr[2]-$dayArr[2]);
        //距离的秒数
        $secs=$now-$time;

        if($todayArr[0]-$dayArr[0]>0 && $days>3){//跨年且超过3天
            return date('Y-m-d',$time);
        }else{

            if($days<1){//今天
                if($secs<60)return $secs.'秒前';
                elseif($secs<3600)return floor($secs/60)."分钟前";
                else return floor($secs/3600)."小时前";
            }else if($days<2){//昨天
                $hour=date('h',$time);
                return "昨天".$hour.'点';
            }elseif($days<3){//前天
                $hour=date('h',$time);
                return "前天".$hour.'点';
            }else{//三天前
                return date('m月d号',$time);
            }
        }
    }else{
        return date($format, $time);
    }
}
/**
 * 生成订单号
 * @return string
 */
function com_order_no($pre = '', $is_db = false)
{
    if($is_db){
        $rs = Db::name('com_code')->find();
        if(!$rs)
            return min(100000000000,999999999999);
        Db::name('com_code')->delete($rs['id']);
        return $rs['code'];
    }
    $id = Db::name('temp_id')->insertGetId(['t' => 1]);
    return $pre . date('Ymd') . (100000000 + $id);
}
/**
 * 获取sql
 */
function com_sql()
{
    $sql = \think\Db::getLastSql();
    t($sql);
}

/**
 * 头像
 * @param  string $pic [description]
 * @return [type]      [description]
 */
function com_avatar($pic=''){
    return $pic?:"/static/www/images/avatar/default.png";
}

/**
 * 统计日志
 * @param unknown $data 统计的日志数据
 * @param string $name  日志文件名
 */
function com_log($data = [], $name = 'log')
{
    if (is_string($data))
        $data = [
            'default' => $data
        ];
    $str = "\r\n-----------------------------------------" . date("Y-m-d H:i:s") . "-----------------------------------------\r\n";
    foreach ($data as $key => $val) {
        $val = is_string($val) ? $val : json_encode($val);
        $str .= "$key:$val\r\n";
    }
    $dir = __DIR__ . "/../public/uploads/logs/" . date("Ym") . "/";
    com_mkdir($dir);
    $file = "$name" . date("Ymd") . ".txt";
    file_put_contents($dir . $file, $str, FILE_APPEND);
}
/**
 * 递归创建目录
 * @param unknown $dir 文件路径
 * @return true or false
 */
function com_mkdir($dir)
{
    if (is_dir($dir) || @mkdir($dir))
        return true;
    if (! com_mkdir(dirname($dir)))
        return false;
    return @mkdir($dir, 0777);
}

/**
 * 获取模块名称
 */
function com_module()
{
    return strtolower(request()->module());
}

/**
 * 获取控制器名称
 */
function com_controller()
{
    return strtolower(request()->controller());
}

/**
 * 获取动作名称
 */
function com_action()
{
    return strtolower(request()->action());
}
